#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
#include <stdbool.h>


//解析文件权限
char* file_mode(mode_t m,char* str)
{
	if(S_ISREG(m))	str[0] = '-';
	else if(S_ISDIR(m))	str[0] = 'd';
	else if(S_ISCHR(m))	str[0] = 'c';
	else if(S_ISBLK(m))	str[0] = 'b';
	else if(S_ISFIFO(m))	str[0] = 'q';
	else if(S_ISLNK(m))	str[0] = 'l';
	else if(S_ISSOCK(m))	str[0] = 's';
	else	str[0] = '?';
	str[1] = '\0';

	strcat(str,S_IRUSR&m?"r":"-");
	strcat(str,S_IWUSR&m?"w":"-");
	strcat(str,S_IXUSR&m?"x":"-");

	strcat(str,S_IRGRP&m?"r":"-");
	strcat(str,S_IWGRP&m?"w":"-");
	strcat(str,S_IXGRP&m?"x":"-");

	strcat(str,S_IROTH&m?"r":"-");
	strcat(str,S_IWOTH&m?"w":"-");
	strcat(str,S_IXOTH&m?"x":"-");

	return str;
}

//判断文件属性
int file_mo(mode_t m,char* dname)
{
	if(S_ISREG(m))	return 1;
	else if(S_ISDIR(m))
	{
		int sum = 0;
		DIR* dp = opendir(dname);
		if(NULL == dp)
		{
			perror("opendir");
			return -1;
		}
		 for(struct dirent* de=readdir(dp);NULL!=de;de=readdir(dp))
		{
			if(de->d_type == DT_DIR)
			{
				sum++;
			}
		}
		return sum;
	}
}

//最后修改时间
char* file_time(time_t t,char* str)
{
	struct tm* it = localtime(&t);
	sprintf(str,"%2d月 %02d %02d:%02d",it->tm_mon+1,it->tm_mday,it->tm_hour,it->tm_min);
	return str;
}


//打印所有数据
void pout(char* name)
{
	struct stat buf = {};
	struct passwd *passwd;
	struct group *group;
	passwd = getpwuid(getuid());//获取用户ID
	group = getgrgid(passwd->pw_gid);//获取组ID
	char y[1024] = {};
	char* file = getcwd(y,sizeof(y));
	if(stat(name,&buf))
	{
		perror("stat");
		return ;
	}
		char str[50] = {};
		printf("%s ",file_mode(buf.st_mode,str));//文件权限
		printf("%d ",file_mo(buf.st_mode,name));//文件属性
		printf("%s ",passwd->pw_name);//用户ID
		printf("%s ",group->gr_name);//组ID
		printf("%5ld ",buf.st_size);//文件大小
		printf("%s ",file_time(buf.st_mtime,str));//文件最后修改时间
		printf("%s\n",name);
}

//判断字符是否大写
bool d_x(char str)
{
	if(str>='A'&&str<='Z') return true;
	return false;
}

//比较函数,如何是大写则在比较时加上32当作小写字母比较
int cmp(char* str1,char* str2)
{
	for(int i=0;str1[i]!='\0'&&str2[i]!='\0';i++)
	{
		if(str1[i]=='.'||str2[i]=='.')break;
		if(d_x(str1[i])&&d_x(str2[i]))
		{
			if(str1[i]>str2[i]) return 1;
			else if(str1[i]<str2[i]) return 0;
		}
		if(d_x(str1[i])&&!d_x(str2[i]))
		{
			if((str1[i]+('a'-'A'))>str2[i]) return 1;
			else if((str1[i]+('a'-'A'))<str2[i]) return 0;
		}
		if(!d_x(str1[i])&&d_x(str2[i]))
		{
			if(str1[i]>(str2[i]+('a'-'A'))) return 1;
			else if(str1[i]<(str2[i]+('a'-'A'))) return 0;
		}
		if(!d_x(str1[i])&&!d_x(str2[i]))
		{
			if(str1[i]>str2[i]) return 1;
			else if(str1[i]<str2[i]) return 0;
		}
	}
	if(strlen(str1)>strlen(str2)) return 1;
	return 0;
}

int main()
{
	char* arr_name[1024];
	char x[1024] = {};
	char* fil = getcwd(x,sizeof(x));
	DIR* dp = opendir(fil);
	if(NULL == dp)
	{
		perror("opendir");
		return -1;
	}
	int size=0;
	for(struct dirent* de=readdir(dp);NULL!=de;de=readdir(dp))
	{
		if('.' == de->d_name[0]) continue;
		arr_name[size] = de->d_name;
		size++;
	}
	for(int i=0;i<size-1;i++)//对文件进行排序
	{
		for(int j=i;j<size;j++)
		{
			if(cmp(arr_name[i],arr_name[j])==1)
			{
				char* temp = arr_name[i];
				arr_name[i] = arr_name[j];
				arr_name[j] = temp;
			}
		}
	}
	for(int i=0;i<size;i++)
	{
		pout(arr_name[i]);
	}
}
